import { Controller } from 'egg';
import queryString = require('querystring'); // 将对象中的值拼接到地址上当参数
import jwt = require('jsonwebtoken');
import { v4 as uuidv4 } from 'uuid';
export default class GithubController extends Controller {
  public async getLoginView() {
    const { ctx } = this;
    // 获取第三方登录界面
    // 发送get请求到https://github.com/login/oauth/authorize带上一些参数即可
    // client_id: Github可以根据这个client_id判断你有没有申请接入
    //            Github可以根据这个client_id查询出对应的应用程序名称,告诉用户正在给哪个程序授权
    // scope    : 授权范围
    const baseURL = 'https://github.com/login/oauth/authorize';
    const option = {
      client_id: '73cee7164770ff0b4225',
      scope: 'user',
    };
    const url = baseURL + '?' + queryString.stringify(option);
    // console.log(url);

    // 重定向到这个地址
    ctx.redirect(url);
  }
  public async getAccessToken() {
    const { ctx } = this;
    // 1.拿到用户同意授权之后的code
    const { code } = ctx.query;
    // 2.利用code换取令牌(access_token)
    // 发送POST请求到https://github.com/login/oauth/access_token带上必要的参数
    const baseURL = 'https://github.com/login/oauth/access_token';
    const option = {
      client_id: '73cee7164770ff0b4225',
      client_secret: 'b6009aebbe46b8f7833a4c94b9f9cdaebead91bc',
      code,
    };
    const result = await ctx.curl(baseURL, {
      method: 'POST',
      data: option,
      dataType: 'json',
      headers: {
        'Content-Type': 'application/json',
        Accept: 'application/json',
      },
    });
      // 获取到令牌
    const accessToken = result.data.access_token;
    console.log(accessToken);
    // 3.拿着令牌去资源服务器获取数据
    await this.getGithubUserInfo(accessToken);
    // console.log(result.data);
  }
  // 拿着令牌去资源服务器获取数据
  private async getGithubUserInfo(accessToken) {
    const { ctx } = this;
    const baseURL = 'https://api.github.com/user';
    const url = `${baseURL}?access_token=${accessToken}`;
    const result = await ctx.curl(url, {
      method: 'GET',
      headers: {
        Authorization: `token ${accessToken}`,
      },
    });
    // console.log(JSON.parse(result.data));
    // ctx.body = 'hello';
    const data = JSON.parse(result.data);
    // 需要用表中 provider 和 uid 去查询用户是否授权
    data.provider = 'github';
    await this.goAdmin(data, accessToken);
  }
  // 查询用户是否有账号, 有就直接登录, 没有则添加一个账号给用户在进入
  private async goAdmin(data, accessToken) {
    const { ctx } = this;
    try {
      // 用户存在, 直接登录
      const user = await ctx.service.oauth.getUser(data);
      // 第一个参数是要生成的对象,第二个参数是密钥 这里用config.keys就可以了
      const token = jwt.sign(user, ctx.app.config.keys, { expiresIn: '7 days' });
      ctx.cookies.set('token', token, {
        path: '/',
        maxAge: 24 * 60 * 60 * 1000,
        // 🔔注意点: 这里不能设置为 true 不然前端无法获取到cookies
        httpOnly: false,
        signed: false, // 不需要签名
      });
      // 跳转到管理界面
      ctx.redirect('http://127.0.0.1:8080/admin');
    } catch (e) {
      // 用户不存在,先注册在登录
      // 1.创建一个用户
      // ctx.body = uuidv4();
      const userInfo = {
        username: uuidv4(),
        password: 'com.123456',
        github: 1,
      };
      const user = await ctx.service.user.createUser(userInfo);
      // 2.保存这个用户的授权信息
      const options = {
        access_token: accessToken,
        provider: data?.provider,
        uid: data?.id,
        user_id: user?.id ? user?.id : -1,
      };
      await ctx.service.oauth.createOauth(options);
      // ctx.body = res;
      // 3.直接登录(跳转到admin界面)
      const token = jwt.sign(user, ctx.app.config.keys, { expiresIn: '7 days' });
      ctx.cookies.set('token', token, {
        path: '/',
        maxAge: 24 * 60 * 60 * 1000,
        // 🔔注意点: 这里不能设置为 true 不然前端无法获取到cookies
        httpOnly: false,
        signed: false, // 不需要签名
      });
      // 跳转到管理界面
      ctx.redirect('http://127.0.0.1:8080/admin');
    }
  }
}
